import 'dart:math';

import 'package:flutter/material.dart';
import 'package:get/get.dart';
/* 
 * @description: 文本提示封装工具
 * @author: Jane 
 * @date: 2023-09-12 16:42:21
 */
class ToastUtils {
  static ToastView? preToast;
  static toast( String msg) {
    var overlayState = Overlay.of(Get.context!);
    var controllerShowAnim = AnimationController(
      vsync: overlayState,
      duration: const Duration(milliseconds: 250),
    );
    var controllerShowOffset = AnimationController(
      vsync: overlayState,
      duration: const Duration(milliseconds: 350),
    );
    var controllerHide = AnimationController(
      vsync: overlayState,
      duration: const Duration(milliseconds: 250),
    );
    var opacityAnim1 = Tween(begin: 0.0, end: 1.0).animate(controllerShowAnim);
    var controllerCurvedShowOffset = CurvedAnimation(
        parent: controllerShowOffset, curve: _BounceOutCurve._());
    var offsetAnim =
        Tween(begin: 30.0, end: 0.0).animate(controllerCurvedShowOffset);
    var opacityAnim2 = Tween(begin: 1.0, end: 0.0).animate(controllerHide);

    OverlayEntry overlayEntry;
    overlayEntry = OverlayEntry(builder: (context) {
      return ToastWidget(
        opacityAnim1: opacityAnim1,
        opacityAnim2: opacityAnim2,
        offsetAnim: offsetAnim,
        child: buildToastLayout(msg),
      );
    });
    var toastView = ToastView();
    toastView.overlayEntry = overlayEntry;
    toastView.controllerShowAnim = controllerShowAnim;
    toastView.controllerShowOffset = controllerShowOffset;
    toastView.controllerHide = controllerHide;
    toastView.overlayState = overlayState;
    preToast = toastView;
    toastView._show();
  }

  static LayoutBuilder buildToastLayout(String msg) {
    return LayoutBuilder(builder: (context, constraints) {
      return IgnorePointer(
        ignoring: true,
        child: Container(
          alignment: Alignment.bottomCenter,
          child: Material(
            color: Colors.white.withOpacity(0),
            child: Container(
              margin: EdgeInsets.only(
                bottom: constraints.biggest.height * 0.15,
                left: constraints.biggest.width * 0.2,
                right: constraints.biggest.width * 0.2,
              ),
              child: Container(
                decoration: BoxDecoration(
                  color: Colors.black.withOpacity(0.6),
                  borderRadius: const BorderRadius.all(
                    Radius.circular(5),
                  ),
                ),
                padding:const EdgeInsets.symmetric(vertical: 10, horizontal: 10),
                child: Text(
                  "${msg}",
                  style: TextStyle(color: Colors.white),
                ),
              ),
            ),
          ),
        ),
      );
    });
  }
}

class ToastView {
  OverlayEntry? overlayEntry;
  AnimationController? controllerShowAnim;
  AnimationController? controllerShowOffset;
  AnimationController? controllerHide;
  OverlayState? overlayState;
  bool dismissed = false;

  _show() async {
    overlayState!.insert(overlayEntry!);
    controllerShowAnim!.forward();
    controllerShowOffset!.forward();
    await Future.delayed(Duration(milliseconds: 3500));
    dismiss();
  }

  dismiss() async {
    if (dismissed) {
      return;
    }
    dismissed = true;
    controllerHide!.forward();
    await Future.delayed(Duration(milliseconds: 250));
    overlayEntry?.remove();
  }
}

class ToastWidget extends StatelessWidget {
  final Widget? child;
  final Animation<double>? opacityAnim1;
  final Animation<double>? opacityAnim2;
  final Animation<double>? offsetAnim;

  ToastWidget(
      {this.child, this.offsetAnim, this.opacityAnim1, this.opacityAnim2});

  @override
  Widget build(BuildContext context) {
    Colors.primaries[Random().nextInt(Colors.primaries.length)];
    return AnimatedBuilder(
      animation: opacityAnim1!,
      child: child,
      builder: (context, child_to_build) {
        return Opacity(
          opacity: opacityAnim1!.value,
          child: AnimatedBuilder(
            animation: offsetAnim!,
            builder: (context, _) {
              return Transform.translate(
                offset: Offset(0, offsetAnim!.value),
                child: AnimatedBuilder(
                  animation: opacityAnim2!,
                  builder: (context, _) {
                    return Opacity(
                      opacity: opacityAnim2!.value,
                      child: child_to_build,
                    );
                  },
                ),
              );
            },
          ),
        );
      },
    );
  }
}

class _BounceOutCurve extends Curve {
  const _BounceOutCurve._();

  @override
  double transform(double t) {
    t -= 1.0;
    return t * t * ((2 + 1) * t + 2) + 1.0;
  }
}
